package dp.mobile.eden;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import dp.mobile.comm.RestClient;
import dp.mobile.game.Score;
import dp.mobile.game.ScoreCollection;
import dp.mobile.level.Level;
import dp.mobile.panel.HorizontalPager;
import dp.mobile.system.SoundManager;
import dp.mobile.system.Utilities;
import dp.mobile.system.XMLReader;

public class HighScoreAct extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.high_score);
		
		initComp();
		initLevels();
		setListener();
		
		//new FetchOnlineScoreTask().execute();
		initHighScoreList();
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mRequestTimer != null)
			mRequestTimer.cancel();
	}
	
	private void initHighScoreList() {
		String levelName = mLevels.get(mCurrLevelIdx).getName();
		
		if(!mLocalHighScores.containsKey(levelName)){
			ScoreCollection highScores = Score.getAllHighScores(getBaseContext(), levelName);
			if(highScores.getHighScores().size() == 0)
				mLocalHighScores.put(levelName, new Integer(-1));
			else
				mLocalHighScores.put(levelName, new Integer(highScores.getHighScores().get(0).getScoreValue()));
		}
		
		int localScore = mLocalHighScores.get(levelName).intValue();
		if(localScore == -1)
			mLocalHighScoreTxtView.setText("You have never played this level");
		else
			mLocalHighScoreTxtView.setText("My highscore is " + mLocalHighScores.get(levelName));
		
		if (mRequestTimer != null)
			mRequestTimer.cancel();
		
		if(!mOnlineScores.containsKey(levelName)){
			mRequestTimer = new Timer();
			mRequestTimer.schedule(new TimerTask() {
				@Override
				public void run() {
					mHandler.sendEmptyMessage(MSG_WHAT_REQUEST_START);
					mReceivedScoreCollection = requestHighScoreList();
					mHandler.sendEmptyMessage(MSG_WHAT_REQUEST_SUCCESS);
				}
			}, 2000);
		}
		else
			mRequestTimer = null;
	}
	
	private Timer mRequestTimer = null;
	
	private static final int MSG_WHAT_REQUEST_START = 0;
	private static final int MSG_WHAT_REQUEST_SUCCESS = 1;
	private static final int MSG_WHAT_REQUEST_FAILED = 2;
	
	private final Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			String levelName = mLevels.get(mCurrLevelIdx).getName();
			if (msg.what == MSG_WHAT_REQUEST_START) {
				if(!mOnlineScores.containsKey(levelName)) //Belum ada di cache, show loading
					m_pgDialog = ProgressDialog.show(HighScoreAct.this, null, "Fetching online scores...", true, true, new DialogInterface.OnCancelListener() {
						@Override
						public void onCancel(DialogInterface dialog) {
							if (mRequestTimer != null)
								mRequestTimer.cancel();
						}
					});
			}
			else if (msg.what == MSG_WHAT_REQUEST_SUCCESS) {
				m_pgDialog.dismiss();
				mOnlineScores.put(levelName, mReceivedScoreCollection);
				ArrayList<Score> scores = mOnlineScores.get(levelName).getHighScores();
				if(scores != null && scores.size() > 0){
					for(int i=0; i<scores.size(); ++i){
						TableRow tr = (TableRow) mHighScoreTables.get(levelName).getChildAt(i+1);

						Log.d("SCORE", scores.get(i).getPlayerName() + "#" + scores.get(i).getScoreValue());
						((TextView)tr.getChildAt(0)).setText(String.valueOf(i+1));
						((TextView)tr.getChildAt(1)).setText(scores.get(i).getPlayerName());
						((TextView)tr.getChildAt(2)).setText(String.valueOf(scores.get(i).getScoreValue()));
					}
				} else{
					TableRow tr = (TableRow) mHighScoreTables.get(levelName).getChildAt(1);
					((TextView)tr.getChildAt(1)).setText("No online highscore yet");
				}
				if (mRequestTimer != null)
					mRequestTimer.cancel();
			}
			else if (msg.what == MSG_WHAT_REQUEST_FAILED) {
				m_pgDialog.dismiss();
			}
		};
	};
	
	private void initLevels(){
		File levelFolder = new File(Utilities.LEVEL_FOLDER); 
		String[] levelFiles = levelFolder.list();
		
		int ctr = 0;
		for (int i = levelFiles.length - 1; i >= 0; --i){
			final String levelFile = levelFiles[i];
			Log.d("HIGHSCORE", "levelFolder levelFile = " + levelFolder + "/" + levelFile);
			mLevels.add(new Level(XMLReader.instance().parseXML(levelFolder + "/" + levelFile), true));

			TableLayout tl = new TableLayout(getBaseContext());
			tl = (TableLayout) getLayoutInflater().inflate(R.layout.high_score_table, null);
			
			mHighScoreTables.put(mLevels.get(ctr).getName(), tl);
			mPager.addView(mHighScoreTables.get(mLevels.get(ctr).getName()));
			++ctr;
		}
		
		mLevelNameTxtView.setText(mLevels.get(mCurrLevelIdx).getName());
	}
	
	private void initComp(){	
		mCurrLevelIdx		= 0;
		mLevelNameTxtView	= (TextView) findViewById(R.id.level_name);
		mLocalHighScoreTxtView	= (TextView) findViewById(R.id.local_highscore_txtview);
		mPager				= (HorizontalPager) findViewById(R.id.horizontal_pager);
		
		mLevels				= new ArrayList<Level>();
		mHighScoreTables	= new HashMap<String, TableLayout>();
		mOnlineScores		= new HashMap<String, ScoreCollection>();
		mLocalHighScores	= new HashMap<String, Integer>();
	}
	
	private void setListener(){
		onScreenSwitchListener  = new HorizontalPager.OnScreenSwitchListener() {
			@Override
			public void onScreenSwitched(int screen) {
				Log.d("HIGHSCORE", "Switched to screen " + screen);
				
				mCurrLevelIdx = screen;
				mLevelNameTxtView.setText(mLevels.get(screen).getName());
				
				//new FetchOnlineScoreTask().execute();
				initHighScoreList();
			}
		};;
		
		mPager.setOnScreenSwitchListener(onScreenSwitchListener);
	}
	
	private ScoreCollection requestHighScoreList() {
		ScoreCollection retval = new ScoreCollection();
		
		Log.d("HIGHSCORE", "http://demeister.com/defenders/public/scripts/get_scores.php?level=" + mLevels.get(mCurrLevelIdx).getName().replace(" " , "%20"));
		try{
			JSONObject tObject = RestClient.get("http://demeister.com/defenders/public/scripts/get_scores.php?level=" + mLevels.get(mCurrLevelIdx).getName().replace(" " , "%20"));
			JSONArray tObjectKeys = tObject.names();
			
			for (int i = 0 ; i < tObjectKeys.length() ; i++) {
				try {
					//String tID = tObjectKeys.getString(i);
					String tID = String.valueOf(i + 1);
					JSONObject tItem = tObject.getJSONObject(tID);
					
					String tName = tItem.getString("name");
					int tScore = tItem.getInt("score");
					long tDate = tItem.getLong("date");
					
					Score tOnlineScore = new Score(tName , "" , tScore , new Date(tDate));
					retval.addScore(tOnlineScore);
					
					//Log.i("this" , tObject.getJSONObject(tID).toString());
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return retval;
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		SoundManager.instance(getBaseContext()).temporarySetMute(true);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		SoundManager.instance(getBaseContext()).temporarySetMute(false);
	}
	
	//ATTRIBUTES
	private ArrayList<Level>	mLevels;
	private int					mCurrLevelIdx;
	private TextView			mLevelNameTxtView, mLocalHighScoreTxtView;
	
	private HashMap<String, ScoreCollection>	mOnlineScores;
	private HashMap<String, TableLayout> 		mHighScoreTables;
	private HashMap<String, Integer>			mLocalHighScores;
	private ScoreCollection						mReceivedScoreCollection;
	 
	private HorizontalPager mPager;
	private HorizontalPager.OnScreenSwitchListener onScreenSwitchListener;
	
	private ProgressDialog	m_pgDialog;
	/*private class FetchOnlineScoreTask extends AsyncTask<Void, Void, Boolean>{
		@Override
		protected Boolean doInBackground(Void... params) {
			String levelName = mLevels.get(mCurrLevelIdx).getName();
			if(!mOnlineScores.containsKey(levelName)){ //Belum ada di cache, ambil
				ScoreCollection tempScore = requestHighScoreList();
				mOnlineScores.put(levelName, tempScore);
			}
			
			if(!mLocalHighScores.containsKey(levelName)){
				ScoreCollection highScores = Score.getAllHighScores(getBaseContext(), levelName);
				if(highScores.getHighScores().size() == 0)
					mLocalHighScores.put(levelName, new Integer(-1));
				else
					mLocalHighScores.put(levelName, new Integer(highScores.getHighScores().get(0).getScoreValue()));
			}

			return null;
		}
		
		@Override
		protected void onPreExecute() {
			String levelName = mLevels.get(mCurrLevelIdx).getName();
			if(!mOnlineScores.containsKey(levelName)) //Belum ada di cache, show loading
				m_pgDialog = ProgressDialog.show(HighScoreAct.this, null, "Fetching online scores...", true);
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			String levelName = mLevels.get(mCurrLevelIdx).getName();
			m_pgDialog.dismiss();
			
			//Online Score
			ArrayList<Score> scores = mOnlineScores.get(levelName).getHighScores();
			if(scores != null && scores.size() > 0){
				for(int i=0; i<scores.size(); ++i){
					TableRow tr = (TableRow) mHighScoreTables.get(levelName).getChildAt(i);

					Log.d("SCORE", scores.get(i).getPlayerName() + "#" + scores.get(i).getScoreValue());
					((TextView)tr.getChildAt(0)).setText(String.valueOf(i+1));
					((TextView)tr.getChildAt(1)).setText(scores.get(i).getPlayerName());
					((TextView)tr.getChildAt(2)).setText(String.valueOf(scores.get(i).getScoreValue()));
				}
			} else{
				TableRow tr = (TableRow) mHighScoreTables.get(levelName).getChildAt(0);
				((TextView)tr.getChildAt(1)).setText("No online highscore yet");
			}
				
			
			//Local Score
			int localScore = mLocalHighScores.get(levelName).intValue();
			if(localScore == -1)
				mLocalHighScoreTxtView.setText("You have never played this level");
			else
				mLocalHighScoreTxtView.setText("My highscore is " + mLocalHighScores.get(levelName));
		}
	}*/
}
